package com.zj.study.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件上传模板实现类
 *
 * @author 赵赳
 * @since 2021/8/25 11:40
 */
@Log4j2
public class TencentOssTemplate implements OssTemplate {


  /**
   * bucket 名称
   */
  private static String bucketName = "images-1306532340";

  /**
   * 基础访问路径
   */
  private static final String BASE_URL =
      "https://" + bucketName + ".cos.ap-guangzhou.myqcloud.com/";


  /**
   * cos 客户端
   */
  private final COSClient client;

  public TencentOssTemplate(String bucketName, String secretId, String secretKey, String region) {
    TencentOssTemplate.bucketName = bucketName;
    COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
    ClientConfig clientConfig = new ClientConfig(new Region(region));
    clientConfig.setHttpProtocol(HttpProtocol.https);
    client = new COSClient(cred, clientConfig);
  }


  @Override
  public String uploadFile(String filePath, String fileName) {
    File localFile = new File(filePath);
    /*日期前缀*/
    var now = LocalDateTime.now();
    var df = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
    var prefix = df.format(now);
    /*文件访问key*/
    var key = prefix + fileName;
    /*上传文件*/
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
    client.putObject(putObjectRequest);
    /*返回文件访问地址*/
    return BASE_URL + key;
  }

  @Override
  public String uploadFile(File file, String fileName) {
    /*日期前缀*/
    LocalDateTime now = LocalDateTime.now();
    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
    String prefix = df.format(now);
    /*文件访问key*/
    String key = prefix + fileName;
    /*上传文件*/
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
    client.putObject(putObjectRequest);
    /*返回文件访问地址*/
    return BASE_URL + key;
  }

  @Override
  public String uploadFile2Cos(MultipartFile file) {
    var originalFilename = file.getOriginalFilename();
    /*日期前缀*/
    var now = LocalDateTime.now();
    var df = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
    var prefix = df.format(now);
    var suffix = "";
    if (originalFilename != null) {
      // .jpg .png
      var substring = originalFilename.substring(originalFilename.lastIndexOf("."));
      var uuid = UUID.randomUUID().toString().replace("-", "");
      suffix = substring + uuid;
    }

    /*文件访问key*/
    String key = prefix + suffix;

    try {
      var inputStream = file.getInputStream();
      // 创建上传Object的Metadata
      ObjectMetadata objectMetadata = new ObjectMetadata();
      objectMetadata.setContentLength(inputStream.available());
      objectMetadata.setCacheControl("no-cache");
      //设置文件类型
      objectMetadata.setContentType(getcontentType(key.substring(key.lastIndexOf("."))));
      var putObjectRequest = new PutObjectRequest(bucketName, key, inputStream,
          objectMetadata);
      client.putObject(putObjectRequest);
    } catch (IOException e) {
      log.debug("上传图片失败！，上传时间：{}", LocalDateTime.now());
      e.printStackTrace();
    }

    /*拼接返回文件访问地址*/
    return BASE_URL + key;
  }


  @Override
  public String uploadFile2Cos(String fileName, InputStream inputStream) throws IOException {
    // 获取文件的后缀名
    String suffixName = fileName.substring(fileName.lastIndexOf("."));
    // 生成上传文件名
    String finalFileName =
        System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + suffixName;
    String objectName =
        DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDateTime.now()) + "/" + finalFileName;

    // 创建上传Object的Metadata
    ObjectMetadata objectMetadata = getObjectMetadata();
    objectMetadata.setContentLength(inputStream.available());
    var putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream,
        objectMetadata);
    client.putObject(putObjectRequest);

    /* 返回文件访问地址 */
    return getUrl(objectName,
        new Calendar.Builder()
            .setDate(1900 + 3000, Calendar.DECEMBER, 31)
            .build().getTime()
    );
  }

  @Override
  public String getUrl(String filepath, Date expiredAt) {
    //return client.getObjectUrl(bucketName,filepath).toString();
    return client
        .generatePresignedUrl(bucketName, filepath, expiredAt)
        .toString();
  }

  private ObjectMetadata getObjectMetadata() {
    return new ObjectMetadata();
  }

  //public static void main(String[] args) {
  //  LocalDateTime now = LocalDateTime.now();
  //  DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
  //  String prefix = df.format(now);
  //  System.out.println("prefix = " + prefix);
  //
  //  String uuid = UUID.randomUUID().toString().replace("-", "");
  //  String str = "15455.jpg";
  //  String substring = str.substring(str.lastIndexOf("."));
  //  System.out.println("substring = " + substring);
  //
  //  String suffix = uuid + substring;
  //
  //  String key = prefix + suffix;
  //  System.out.println("key = " + key);
  //
  //  Random random = new Random();
  //  //生成新的图片名称(随机数0-9999+系统当前时间+上传图片名)
  //  String fileKey = random.nextInt(10000) + "" + System.currentTimeMillis() + substring;
  //  String fileKey1 = random.nextInt(10000) + System.currentTimeMillis() + substring;
  //  System.out.println("fileKey1 = " + fileKey1);
  //  System.out.println("name = " + fileKey);
  //}


  /**
   * Description: 判断Cos服务文件上传时文件的contentType
   *
   * @param filenameExtension 文件后缀
   * @return String
   */
  public static String getcontentType(String filenameExtension) {
    if (filenameExtension.equalsIgnoreCase("bmp")) {
      return "image/bmp";
    }
    if (filenameExtension.equalsIgnoreCase("gif")) {
      return "image/gif";
    }
    if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")
        || filenameExtension.equalsIgnoreCase("png")) {
      return "image/jpeg";
    }
    if (filenameExtension.equalsIgnoreCase("html")) {
      return "text/html";
    }
    if (filenameExtension.equalsIgnoreCase("txt")) {
      return "text/plain";
    }
    if (filenameExtension.equalsIgnoreCase("vsd")) {
      return "application/vnd.visio";
    }
    if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) {
      return "application/vnd.ms-powerpoint";
    }
    if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {
      return "application/msword";
    }
    if (filenameExtension.equalsIgnoreCase("xml")) {
      return "text/xml";
    }
    return "image/jpeg";
  }


}
